<?php
  
    /**
    * AES Encryption Class
    * @author Matthew Dahl
    * @copyright Copyright (c) 2011 Mintrus, LLC. <http://mintrus.com>
    * @version 1.0
    */
    class AESCipher
    {
        /**
        * @access private
        * @internal
        * @since 1.0
        * @var reference Encryption descriptor
        */
        private $_cipher;
  
        /**
        * @access private
        * @internal
        * @since 1.0
        * @var constant|string One of the MCRYPT_MODE_modename constants, or one of the following strings: "ecb", "cbc", "cfb", "ofb", "nofb" or "stream"
        */
        private $_mode;
  
        /**
        * @access private
        * @internal
        * @since 1.0
        * @var string Contains padding mode for encryption/decryption
        */
        private $_paddingType;
  
        /**
        * @access public
        * @param constant|string @mode One of the MCRYPT_MODE_modename constants, or one of the following strings: "ecb", "cbc", "cfb", "ofb", "nofb" or "stream"
        * @since 1.0
        */
        public function AESCipher($mode)
        {
            $this->_mode               = $mode;
            $this->_cipher           = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $this->_mode, '');
            $this->_paddingType = 'PKCS7';
        }
  
        /**
        * @access public
        * @param string @data The data you want to decrypt
        * @param string @key Encryption key
        * @param string @iv Initialization vector
        * @return string Decrypted data
        * @since 1.0
        */
        public function decrypt($data, $key, $iv)
        {
            mcrypt_generic_init($this->_cipher, $key, $iv);
            $result = mdecrypt_generic($this->_cipher, $data);
            mcrypt_generic_deinit($this->_cipher);
  
            if ($this->_paddingType == 'PKCS7')
            {
                return $this->RemovePKCS7Padding($result);
            }
            else
            {
                return $result;
            }
        }
  
        /**
        * @access public
        * @param string @data The data you want to encrypt
        * @param string @key Encryption key
        * @param string @iv Initialization vector
        * @return string Encrypted data
        * @since 1.0
        */
        public function encrypt($data, $key, $iv)
        {
            if ($this->_paddingType == 'PKCS7')
            {
                $data = $this->AddPKCS7Padding($data);
            }
  
            mcrypt_generic_init($this->_cipher, $key, $iv);
            $result = mcrypt_generic($this->_cipher, $data);
            mcrypt_generic_deinit($this->_cipher);
  
            return $result;
        }
  
        /**
        * @access public
        * @param string Padding mode ("PKCS7" or "zero")
        * @since 1.0
        */
        public function padding($type)
        {
            if ($type == 'PKCS7')
            {
                $this->_paddingType = 'PKCS7';
            }
            else
            {
                $this->_paddingType = 'zero';
            }
        }
  
        /**
        * This adds PKCS7 padding to comply with many other AES implementations such as AESManaged for WP7
        * @access private
        * @internal
        * @param string Data to add padding to
        * @return string Data with PKCS7 padding
        * @since 1.0
        */
        private function AddPKCS7Padding($data)
        {
            //$block = mcrypt_get_block_size('des', $this->_mode);
            $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, $this->_mode);
            $pad     = $block - (strlen($data) % $block);
            $data .= str_repeat(chr($pad), $pad);
            return $data;
        }
  
        /**
        * @access private
        * @internal
        * @param string Data to remove padding from
        * @return string Data with PKCS7 padding removed
        * @since 1.0
        */
        private function RemovePKCS7Padding($data)
        {
            //$block = mcrypt_get_block_size('des', $this->_mode);
            $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, $this->_mode);
            $pad     = ord($data[($len = strlen($data)) - 1]);
            return substr($data, 0, strlen($data) - $pad);
        }
  
    }
  
?>